/**
 * Copyright 2000 self.com.au
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License. (http://www.apache.org/licenses/LICENSE-2.0)
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed 
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for 
 * the specific language governing permissions and limitations under the License.
 *
 * <dhamma-message src="Atisha (11th century Tibetan Buddhist master)">
 * 	The greatest achievement is selflessness. The greatest worth is self-mastery.
 * 	The greatest quality is seeking to serve others. The greatest precept is continual awareness.
 * 	The greatest medicine is the emptiness of everything. The greatest action is not conforming with the worlds ways.
 * 	The greatest magic is transmuting the passions. The greatest generosity is non-attachment.
 * 	The greatest goodness is a peaceful mind. The greatest patience is humility.
 * 	The greatest effort is not concerned with results. The greatest meditation is a mind that lets go.
 * 	The greatest wisdom is seeing through appearances. 
 * </dhamma-message>
 *
 * @author Ashin Wimalajeewa
 */
package self.amigo.editor.sheet;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JColorChooser;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.border.Border;
import javax.swing.border.EtchedBorder;
import javax.swing.border.TitledBorder;

import self.amigo.editor.APropertySheet;
import self.amigo.editor.cmd.PropertiesChange;
import self.amigo.elem.AGraphicElement;
import self.amigo.elem.LineSideFeature;
import self.amigo.elem.LinkView;
import self.amigo.elem.PolyElementView;
import self.amigo.elem.PolyLineView;
import self.awt.layout.VerticalFlowLayout;
import self.gee.IEditableElement;
import self.gee.IPointSeriesElement;
import self.gee.editor.IPropertySheet;

public class LineSheet extends APropertySheet implements IPropertySheet {
	
	/**
	 * If the internal state of this class ever changes in such a way that it can't be defaulted,
	 * then the {@link #serialVersionUID} should be incremented to ensure serialized instances cleanly fail.  
	 */
	private static final long serialVersionUID = 1;
	
  JTabbedPane         propertySheet = new JTabbedPane();
  BorderLayout        contentPaneLayout = new BorderLayout();

  JPanel              generalTab = new JPanel();
  VerticalFlowLayout  generalPaneLayout = new VerticalFlowLayout();
  JPanel              generalPane = new JPanel();
  JScrollPane         generalScroller = new JScrollPane();
  BorderLayout        generalLayout = new BorderLayout();

  JPanel              lineTab = new JPanel();
  VerticalFlowLayout  linePaneLayout = new VerticalFlowLayout();
  JPanel              linePane = new JPanel();
  JScrollPane         lineScroller = new JScrollPane();
  BorderLayout        lineLayout = new BorderLayout();

  JPanel              polygonTab = new JPanel();
  VerticalFlowLayout  polygonPaneLayout = new VerticalFlowLayout();
  JPanel              polygonPane = new JPanel();
  JScrollPane         polygonScroller = new JScrollPane();
  BorderLayout        polygonLayout = new BorderLayout();

  JLabel headerLabel = new JLabel();
  JTextField header = new JTextField();
  VerticalFlowLayout verticalFlowLayout1 = new VerticalFlowLayout();
  JLabel nameLabel = new JLabel();
  JTextField name = new JTextField();
  JCheckBox dashed = new JCheckBox();
  JPanel sideA = new JPanel();
  Border border1;
  TitledBorder titledBorder1;
  TitledBorder titledBorder2;
  JLabel headALabel = new JLabel();
  VerticalFlowLayout verticalFlowLayout2 = new VerticalFlowLayout();
  JComboBox headA = new JComboBox();
  JLabel majorALabel = new JLabel();
  JTextField majorA = new JTextField();
  JLabel minorALabel = new JLabel();
  JTextField minorA = new JTextField();
  JLabel majorBLabel = new JLabel();
  JComboBox headB = new JComboBox();
  JPanel sideB = new JPanel();
  JLabel minorBLabel = new JLabel();
  VerticalFlowLayout verticalFlowLayout3 = new VerticalFlowLayout();
  JTextField majorB = new JTextField();
  JLabel headBLabel = new JLabel();
  JTextField minorB = new JTextField();
  JComboBox frameColor = new JComboBox();
  JLabel headDiameterLabel = new JLabel();
  JTextField headDiameter = new JTextField();

  JLabel frameColorLabelTxt = new JLabel();

  JPanel colorPanel = new JPanel();
  JLabel frameColorLabel = new JLabel();
  JButton frameColorBtn = new JButton();

  JCheckBox polygon = new JCheckBox();
  JPanel polygonGrad1ColorPanel = new JPanel();
  JLabel polygonGrad1ColorLabel = new JLabel();
  JButton polygonGrad1ColorBtn = new JButton();

  JPanel polygonGrad2ColorPanel = new JPanel();
  JLabel polygonGrad2ColorLabel = new JLabel();
  JButton polygonGrad2ColorBtn = new JButton();

  JLabel fillEffectStyleLabel = new JLabel();
  JTextField fillEffectStyleSpec = new JTextField();

  FlowLayout flowLayout1 = new FlowLayout();

  JPanel removeFillPane = new JPanel();
  JButton removeFillBtn = new JButton();
  JCheckBox showFrameBtn = new JCheckBox();

  JLabel lineWidthLabel = new JLabel();
  JTextField lineWidth = new JTextField();

  private IEditableElement view;
  private boolean isPolyElement;
  private Color                      currColor;
  private Color                      currGrad1Color;
  private Color                      currGrad2Color;

  public LineSheet() {
    try {
      jbInit();
      headA.setModel( PolyLineView.createHeadModel() );
      headB.setModel( PolyLineView.createHeadModel() );
//      frameColor.setModel( APropertySheet.createColorModel() );
    } catch(Exception e) {
      e.printStackTrace();
    }
  }

  private void jbInit() throws Exception {
    border1 = new EtchedBorder(EtchedBorder.RAISED,Color.white,new Color(134, 134, 134));
    titledBorder1 = new TitledBorder(border1,"Side A");
    titledBorder2 = new TitledBorder(border1,"Side B");
    this.setLayout(contentPaneLayout);

    frameColorLabelTxt.setText("frame color");
    polygon.setText("polygon");

    headerLabel.setText("header");
    nameLabel.setText("name");
    dashed.setText("dashed");
//    dashed.setHorizontalTextPosition(SwingConstants.LEFT);
    sideA.setBorder(titledBorder1);
    sideA.setLayout(verticalFlowLayout2);
    headALabel.setText("head");
    majorALabel.setText("major");
    minorALabel.setText("minor");
    majorBLabel.setText("major");
    sideB.setLayout(verticalFlowLayout3);
    sideB.setBorder(titledBorder2);
    minorBLabel.setText("minor");
    headBLabel.setText("head");

    headDiameterLabel.setText("head diameter");
    removeFillBtn.setText("remove fill");
    removeFillBtn.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        removeFillBtn_actionPerformed(e);
      }
    });
    showFrameBtn.setText("show frame");
    lineWidthLabel.setText("line width");
    sideA.add(headALabel, null);
    sideA.add(headA, null);
    sideA.add(majorALabel, null);
    sideA.add(majorA, null);
    sideA.add(minorALabel, null);
    sideA.add(minorA, null);

    sideB.add(headBLabel, null);
    sideB.add(headB, null);
    sideB.add(majorBLabel, null);
    sideB.add(majorB, null);
    sideB.add(minorBLabel, null);
    sideB.add(minorB, null);

    generalPane.add(frameColorLabelTxt, null);
    generalPane.add(colorPanel, null);
    generalPane.add(polygon, null);
    generalPane.add(dashed, null);

    generalPane.setLayout(generalPaneLayout);
    generalScroller.getViewport().add( generalPane, null );
    generalPane.add(lineWidthLabel, null);
    generalPane.add(lineWidth, null);
    generalTab.setLayout(generalLayout);
    generalTab.add( generalScroller, BorderLayout.CENTER );

    linePane.setLayout( linePaneLayout );
    linePane.add(headerLabel, null);
    linePane.add(header, null);
    linePane.add(nameLabel, null);
    linePane.add(name, null);
    linePane.add(headDiameterLabel, null);
    linePane.add(headDiameter, null);
    linePane.add(sideA, null);
    linePane.add(sideB, null);

    linePane.setLayout(linePaneLayout);
    lineScroller.getViewport().add( linePane, null );
    lineTab.setLayout(lineLayout);
    lineTab.add( lineScroller, BorderLayout.CENTER );

    frameColorLabel.setBackground(new Color(192, 192, 20));
    frameColorLabel.setOpaque(true);
    frameColorLabel.setText("               ");
    frameColorBtn.setPreferredSize(new Dimension(30, 16));
    frameColorBtn.setText("...");
    frameColorBtn.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        frameColorBtn_actionPerformed(e);
      }
    });
    colorPanel.setLayout(flowLayout1);
    flowLayout1.setAlignment(FlowLayout.LEFT);
    colorPanel.add(frameColorLabel, null);
    colorPanel.add(frameColorBtn, null);

    this.add(propertySheet, BorderLayout.CENTER);

    polygonGrad1ColorLabel.setBackground(new Color(192, 192, 20));
    polygonGrad1ColorLabel.setOpaque(true);
    polygonGrad1ColorLabel.setText("               ");
    polygonGrad1ColorBtn.setPreferredSize(new Dimension(30, 16));
    polygonGrad1ColorBtn.setText("...");
    polygonGrad1ColorBtn.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        polygonGrad1ColorBtn_actionPerformed(e);
      }
    });
    polygonGrad1ColorPanel.setLayout(flowLayout1);
    polygonGrad1ColorPanel.add(polygonGrad1ColorLabel, null);
    polygonGrad1ColorPanel.add(polygonGrad1ColorBtn, null);
    polygonGrad1ColorPanel.add(new JLabel(" gradient 1"), null);

    polygonGrad2ColorLabel.setBackground(new Color(192, 192, 20));
    polygonGrad2ColorLabel.setOpaque(true);
    polygonGrad2ColorLabel.setText("               ");
    polygonGrad2ColorBtn.setPreferredSize(new Dimension(30, 16));
    polygonGrad2ColorBtn.setText("...");
    polygonGrad2ColorBtn.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        polygonGrad2ColorBtn_actionPerformed(e);
      }
    });
    polygonGrad2ColorPanel.setLayout(flowLayout1);
    polygonGrad2ColorPanel.add(polygonGrad2ColorLabel, null);
    polygonGrad2ColorPanel.add(polygonGrad2ColorBtn, null);
    polygonGrad2ColorPanel.add(new JLabel(" gradient 2"), null);

    polygonPane.setLayout(polygonPaneLayout);
    polygonScroller.getViewport().add( polygonPane, null );
    polygonPane.add(removeFillPane, null);
    removeFillPane.add(showFrameBtn, null);
    removeFillPane.add(removeFillBtn, null);
    polygonTab.setLayout(polygonLayout);
    polygonTab.add( polygonScroller, BorderLayout.CENTER );
    removeFillPane.setLayout( flowLayout1 );

    fillEffectStyleLabel.setText( "Fill effect style" );
    polygonPane.setLayout( polygonPaneLayout );
    polygonPane.add( polygonGrad1ColorPanel, null );
    polygonPane.add( polygonGrad2ColorPanel, null );
    polygonPane.add( fillEffectStyleLabel, null );
    polygonPane.add( fillEffectStyleSpec, null );

    propertySheet.add(generalTab, "General");
    propertySheet.add(lineTab, "Line");
    propertySheet.add(polygonTab, "Polygon");
  }

  public void inspect( Object toDisplay ) {
    if ( (toDisplay instanceof PolyElementView) || (toDisplay instanceof PolyLineView) || (toDisplay instanceof LinkView)) {
//    if ( (toDisplay instanceof PolyLineView) || (toDisplay instanceof LinkView)) {
      view = (IEditableElement) toDisplay;
      isPolyElement = (toDisplay instanceof PolyElementView);
      polygon.setVisible( false );
      if ( isPolyElement ) {
        if ( propertySheet.getTabCount() == 2 )
          propertySheet.add( polygonTab, "Polygon" );
        polygon.setVisible( true );
      } else
        propertySheet.remove( polygonTab );
      revert();
    } else
      throw new RuntimeException( "Invalid Graphic element to display:" + toDisplay );
  }

  public void accept() {
    if ( view == null )
      return;

    store.put( AGraphicElement.FRAMECOLOR_PROP, currColor );
    store.put( PolyLineView.WIDTH_PROP, lineWidth.getText() );

    if ( polygon.isVisible() ) {
      int points = ((IPointSeriesElement)view).getNoOfPoints();
      polygon.setEnabled( points > 2 );
      Boolean poly = new Boolean( polygon.isSelected() && polygon.isEnabled() );
      store.put( PolyLineView.POLYGON_PROP, poly );
    } else
      store.put( PolyLineView.POLYGON_PROP, Boolean.FALSE );

    Boolean polyFrame = new Boolean( showFrameBtn.isSelected() );
    store.put( PolyLineView.POLYGON_FRAME_PROP, polyFrame );
    store.put( PolyLineView.POLYGON_FILL1_PROP, currGrad1Color );
    store.put( PolyLineView.POLYGON_FILL2_PROP, currGrad2Color );
    store.put( PolyLineView.POLYGON_FILL_STYLE_PROP, fillEffectStyleSpec.getText() );

    store.put( PolyLineView.HEADER_PROP, header.getText() );
    store.put( PolyLineView.NAME_PROP, name.getText() );
    Boolean dash = new Boolean( dashed.isSelected() );
    store.put( PolyLineView.DASHED_PROP, dash );

    LineSideFeature side = (LineSideFeature) store.get( PolyLineView.SIDEA_PROP );
    side.head = headA.getSelectedIndex();
    side.major = majorA.getText();
    side.minor = minorA.getText();

    side = (LineSideFeature) store.get( PolyLineView.SIDEB_PROP );
    side.head = headB.getSelectedIndex();
    side.major = majorB.getText();
    side.minor = minorB.getText();

    store.put( PolyLineView.HEAD_DIAMETER_PROP, headDiameter.getText() );

    PropertiesChange cmd = new PropertiesChange( editor, view, store );
    cmd.executeIfRequired();
  }

  public void revert() {
    if ( view == null )
      return;

    if ( polygon.isVisible() ) {
      int points = ((IPointSeriesElement)view).getNoOfPoints();
      polygon.setEnabled( points > 2 );
    }

    store.clear();
    view.getProperties( store );

    lineWidth.setText( (String) store.get(PolyLineView.WIDTH_PROP) );

    polygon.setSelected( ((Boolean)store.get(PolyLineView.POLYGON_PROP)).booleanValue() );
    showFrameBtn.setSelected( ((Boolean)store.get(PolyLineView.POLYGON_FRAME_PROP)).booleanValue() );
    currGrad1Color = (Color) store.get( PolyLineView.POLYGON_FILL1_PROP );
    polygonGrad1ColorLabel.setBackground( currGrad1Color );
    currGrad2Color = (Color) store.get( PolyLineView.POLYGON_FILL2_PROP );
    polygonGrad2ColorLabel.setBackground( currGrad2Color );
    fillEffectStyleSpec.setText( (String) store.get(PolyLineView.POLYGON_FILL_STYLE_PROP) );

    currColor = (Color) store.get( AGraphicElement.FRAMECOLOR_PROP );
    frameColorLabel.setBackground( currColor );

    header.setText( (String) store.get(PolyLineView.HEADER_PROP) );
    name.setText( (String) store.get(PolyLineView.NAME_PROP) );
    dashed.setSelected( ((Boolean)store.get(PolyLineView.DASHED_PROP)).booleanValue() );
    LineSideFeature localSideA = (LineSideFeature) store.get( PolyLineView.SIDEA_PROP );
    headA.setSelectedIndex( localSideA.head );
    majorA.setText( localSideA.major );
    minorA.setText( localSideA.minor );

    LineSideFeature localSideB = (LineSideFeature) store.get( PolyLineView.SIDEB_PROP );
    headB.setSelectedIndex( localSideB.head );
    majorB.setText( localSideB.major );
    minorB.setText( localSideB.minor );
    headDiameter.setText( (String) store.get(PolyLineView.HEAD_DIAMETER_PROP) );
  }

  public Object getObjectUnderInspection() {
    return view;
  }

  void frameColorBtn_actionPerformed(ActionEvent e) {
    Color c = querySelectColor( "Select line frame color", currColor );
    if ( c != null ) {
      currColor = c;
      frameColorLabel.setBackground( c );
    }
  }

  void polygonGrad1ColorBtn_actionPerformed(ActionEvent e) {
    Color c = querySelectColor( "Select fill gradient color 1", currGrad1Color );
    if ( c != null ) {
      currGrad1Color = c;
      polygonGrad1ColorLabel.setBackground( c );
    }
  }

  void polygonGrad2ColorBtn_actionPerformed(ActionEvent e) {
    Color c = querySelectColor( "Select fill gradient color 2", currGrad2Color );
    if ( c != null ) {
      currGrad2Color = c;
      polygonGrad2ColorLabel.setBackground( c );
    }
  }

  private Color querySelectColor( String title, Color curr ) {
		return JColorChooser.showDialog( this, title,  curr );
  }

  void removeFillBtn_actionPerformed(ActionEvent e) {
    currGrad1Color = null;
    currGrad2Color = null;
    polygonGrad1ColorLabel.setBackground( currGrad1Color );
    polygonGrad2ColorLabel.setBackground( currGrad2Color );
  }

//  static public void main( String[] args ) {
//    JFrame form = new JFrame( "test" );
//    LineSheet sheet = new LineSheet();
//    form.getContentPane().add( sheet );
//    form.show();
//  }
}
